import dayjs, { type ManipulateType, type Dayjs } from 'dayjs'
import type { App, Plugin } from 'vue'

export const withInstall = <T>(component: T, alias?: string) => {
  const comp = component as any
  comp.install = (app: App) => {
    app.component(comp.name || comp.displayName, comp)
    if (alias) {
      app.config.globalProperties[alias] = component
    }
  }
  return component as T & Plugin
}

/** 白屏时间 */
export const blankTime = () => {
  const t: any = performance.getEntriesByType('navigation')[0]
  const value = (t?.domInteractive ?? t?.domLoading ?? 0) - t?.fetchStart
  return `${value.toLocaleString()}ms`
}

/**
 * 时间戳转日期时间
 * @param {number} date 时间戳
 * @param {string} template 转换格式
 * @returns
 */
export const formatUnix = (
  date: number,
  template: string = 'YYYY-MM-DD HH:mm:ss'
): string => {
  return date ? dayjs.unix(date).format(template) : '-'
}
/**
 * 格式化数字
 * @param {number} number 数字
 * @returns
 */
// export const formatNumber = (number: number) => {
//   const str = number.toString()
//   const ind = str.length % 3
//   const strFront = str.slice(0, ind)
//   const strBehind = str.slice(ind)
//   const arr: string[] = []
//   for (let i = 0; i < strBehind.length; i += 3) {
//     arr.push(strBehind.slice(i, i + 3))
//   }
//   if (ind) {
//     arr.unshift(strFront)
//   }
//   return arr.join()
// }
export const formatNumber = (number: number) => {
  const str = number.toString()
  return str.replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}

// 判断返回单位
export const judgeUnit = (time: number, timeUnit: string = 'day') => {
  if (timeUnit === 'day') {
    return formatUnix(time, 'HH:mm')
  }
  if (timeUnit === 'week') {
    // return formatUnix(time, 'MM-DD HH:mm')
    return formatUnix(time, 'MM-DD')
  }
  if (timeUnit === 'halfMonth') {
    // return formatUnix(time, 'MM-DD HH:mm')
    return formatUnix(time, 'MM-DD')
  }
  if (timeUnit === 'month') {
    return formatUnix(time, 'MM-DD')
  }
  return '-'
}
/**
 * 获取填充后的数据
 * dataSource 原数据
 * startTime 开始时间戳
 * endTime 结束时间戳
 *
 */
export const getChartData = (
  dataSource: any = [],
  startTime = 0,
  endTime = 0,
  field = '',
  timeFiled = 'time_day'
) => {
  const minute = endTime - startTime
  let unit = 'day'
  if (minute <= 86400) {
    unit = 'day'
  } else if (minute <= 86400 * 7) {
    unit = 'week'
  } else if (minute <= 86400 * 15) {
    unit = 'halfMonth'
  } else {
    unit = 'month'
  }

  const length: Record<string, () => number> = {
    day: () => minute / 300,
    week: () => minute / 86400,
    halfMonth: () => minute / 86400,
    month: () => minute / 86400
  }
  const addUnit: Record<string, string> = {
    day: 'minute',
    week: 'days',
    halfMonth: 'days',
    month: 'days'
  }

  if (!startTime || !endTime || !field || !unit) {
    console.warn('startTime, endTime, field and unit are required parameters')
    return { seriesData: [], xAxisData: [] }
  }
  const keys = dataSource.map((item: any) => {
    return +item[timeFiled]
  })
  const seriesData = dataSource.map((item: any) => +item[field])
  //   const xAxisData = Array.from({ length: length[unit]() + 1 }, (_, i) => {
  //     const time = dayjs(dayjs.unix(startTime))
  //       .add(unit === 'day' ? 5 * i : i + 1, addUnit[unit] as ManipulateType)
  //       .unix()
  //     if (!keys.includes(time)) {
  //       seriesData.splice(i, 0, getUnix() - 300 > time ? 0 : '-')
  //     }
  //     return time
  //   })

  const xAxisData = Array.from({ length: length[unit]() + 1 }, (_, i) => {
    const time = dayjs(dayjs.unix(startTime))
      .add(unit === 'day' ? 5 * i : i, addUnit[unit] as ManipulateType)
      .unix()
    if (!keys.includes(time)) {
      seriesData.splice(i, 0, getUnix() - 300 > time ? 0 : '-')
    }
    return time
  })
  return { seriesData, xAxisData, unit }
}
/**
 * 获取时间戳 如果不传date 获取当前时间
 * @param {*} ？date 时间
 * @returns
 */
type DateInput = string | number | Date | Dayjs | null | undefined
export const getUnix = (date?: DateInput): number => dayjs(date).unix()
/**
 * 获取传入时间的00:00:00 的时间戳  默认 当前时间
 * @returns
 */
export const getUnixZero = (date?: number) => {
  const dateTime = typeof date === 'number' ? dayjs.unix(date) : dayjs(date)
  return dateTime.hour(0).minute(0).second(0).unix()
}
/**
 * 获取传入时间字符串 例:'56'
 * @returns 00:00:56
 */
export const formatSeconds = (value: string) => {
  const result = parseInt(value)
  const h = `${Math.floor(result / 3600)}`.padStart(2, '0')
  const m = `${Math.floor((result / 60) % 60)}`.padStart(2, '0')
  const s = `${Math.floor(result % 60)}`.padStart(2, '0')
  return `${h}:${m}:${s}`
}
// export const formatSeconds = (value: string) => {
//   const result = parseInt(value)
//   const h =
//     Math.floor(result / 3600) < 10
//       ? '0' + Math.floor(result / 3600)
//       : Math.floor(result / 3600)
//   const m =
//     Math.floor((result / 60) % 60) < 10
//       ? '0' + Math.floor((result / 60) % 60)
//       : Math.floor((result / 60) % 60)
//   const s =
//     Math.floor(result % 60) < 10
//       ? '0' + Math.floor(result % 60)
//       : Math.floor(result % 60)
//   let res = ''
//   // if (h !== '00') res += `${h}:${m}:`
//   // if (h === '00') res += `00:${m}:`
//   res += `${h}:${m}:${s}`
//   return res
// }
/** 随机生成固定位数或者一定范围内的字符串数字组合
 * @param {Number} min 范围最小值
 * @param {Number} max 范围最大值，当不传递时表示生成指定位数的组合
 * @returns {String} 返回字符串结果
 * */
export const randomRange = (min, max = undefined) => {
  let returnStr = ''
  const arr = `0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`
  const range = max ? Math.round(Math.random() * (max - min)) + min : min

  for (let i = 0; i < range; i++) {
    const index = Math.round(Math.random() * (arr.length - 1))
    returnStr += arr[index]
  }
  return returnStr
}
